package org.ch02.test09.demo00;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;

/**
 * @author CSY
 * @date 2025 - 03 - 25
 */
public class BeanUtil {
    /**
     * 设置何意对象的属性值
     * @param bean 对象
     * @param propertyName 属性名称
     * @param value 值
     */
    public static void setProperty(Object bean, String propertyName, Object value){
        try {
            //获取到属性对象
            PropertyDescriptor propertyDescriptor = new PropertyDescriptor(propertyName,bean.getClass());
            //获取到setter
            Method writeMethod = propertyDescriptor.getWriteMethod();
            //调用setter
            writeMethod.invoke(bean,value);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取任意对象的属性值
     * @param bean
     * @param propertyName
     * @return
     */
    public static Object getProperty(Object bean, String propertyName){
        try {
            //获取属性对象
            PropertyDescriptor propertyDescriptor = new PropertyDescriptor(propertyName,bean.getClass());
            //获取getter
            Method readMethod = propertyDescriptor.getReadMethod();
            //调用getter并返回
            return readMethod.invoke(bean);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 复制某个对象的属性值到另一个对象中
     * @param sourceBean 源Bean对象
     * @param targetBean 目标Bean对象
     */
    public static void copyProperties(Object sourceBean, Object targetBean){
        if (sourceBean.getClass() != targetBean.getClass()){
            throw new RuntimeException("对象不一致！");
        }
        try {
            //获取到其中一个对象的BeanInfo对象 - 因为两个对象的类必定相同所以获取其中一个即可吧
            BeanInfo beanInfo = Introspector.getBeanInfo(sourceBean.getClass(), Object.class);
            //根据BeanInfo获取到所有属性
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            //循环遍历所有属性
            for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
                //获取属性名
                String propertyName = propertyDescriptor.getName();

                Object property = getProperty(sourceBean, propertyName);
                setProperty(targetBean, propertyName, property);
                //获取getter
//                Method readMethod = propertyDescriptor.getReadMethod();

                //获取setter
//                Method writeMethod = propertyDescriptor.getWriteMethod();
                //调用目标对象的setter方法 - 调用源对象的getter方法
//                writeMethod.invoke(targetBean,readMethod.invoke(sourceBean));
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }
}
